﻿namespace Example
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using Xunit;

    public class TcpClientFacts
    {
        [Fact]
        public void ctor_string_int()
        {
            TcpClient client = null;
            try
            {
                client = new TcpClient("example.com", 80);
            }
            finally
            {
                if (null != client)
                {
                    client.Close();
                }
            }
        }

        [Fact]
        public void ctor_string_intInvalid()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new TcpClient("127.0.0.1", 99999));
        }

        [Fact]
        public void ctor_string_intUnavailable()
        {
            Assert.Throws<SocketException>(() => new TcpClient("127.0.0.1", 65432));
        }

        [Fact(Skip = "example.com has changed.")]
        public void op_GetStream_whenAsync()
        {
            var tcp = new TcpClient();
            try
            {
                Uri proxy;
                using (var web = new WebClient())
                {
                    proxy = web.Proxy.GetProxy(new Uri("http://example.com/"));
                }

                var connection = tcp.BeginConnect(proxy.DnsSafeHost, proxy.Port, null, null);
                var connected = connection.AsyncWaitHandle.WaitOne(5000, true);
                if (connected)
                {
                    tcp.EndConnect(connection);
                    using (var stream = tcp.GetStream())
                    {
                        using (var writer = new StreamWriter(stream))
                        {
                            writer.WriteLine("GET / HTTP/1.1");
                            writer.WriteLine("Host: example.com");
                            writer.WriteLine("Connection: Close");
                            writer.WriteLine(string.Empty);
                            writer.Flush();
                            using (var reader = new StreamReader(stream))
                            {
                                Assert.True(reader.ReadToEnd().StartsWith("HTTP/1.1 200 OK"));
                            }
                        }
                    }
                }
                else
                {
                    tcp.Close();
                }
            }
            finally
            {
                tcp.Close();
            }
        }

        [Fact(Skip = "example.com has changed.")]
        public void op_GetStream_whenSync()
        {
            TcpClient tcp = null;
            try
            {
                Uri proxy;
                using (var web = new WebClient())
                {
                    proxy = web.Proxy.GetProxy(new Uri("http://example.com/"));
                }

                tcp = new TcpClient(proxy.DnsSafeHost, proxy.Port);
                using (var stream = tcp.GetStream())
                {
                    using (var writer = new StreamWriter(stream))
                    {
                        writer.WriteLine("GET / HTTP/1.1");
                        writer.WriteLine("Host: example.com");
                        writer.WriteLine("Connection: Close");
                        writer.WriteLine(string.Empty);
                        writer.Flush();
                        using (var reader = new StreamReader(stream))
                        {
                            Assert.True(reader.ReadToEnd().StartsWith("HTTP/1.1 200 OK"));
                        }
                    }
                }
            }
            finally
            {
                if (null != tcp)
                {
                    tcp.Close();
                }
            }
        }
    }
}